-module(clientovich).
-compile(export_all).

-define(TCP_OPTIONS, [list, {packet,    0},
                            {active,    false},
                            {reuseaddr, true}]).

start(Address,Port) ->
    case is_started() of
        true  -> {alredy_started};
        false ->
            register(?MODULE,spawn(?MODULE,loop,[0])),
            ?MODULE ! {start, Address, Port}
    end.
    
simple_start() ->
    start("localhost",25000).

put(Key,Value) ->
    ?MODULE ! {put,Key,Value,self()},
    receive
        {reply,Reply} -> Reply
    end.

get(Key) ->
    ?MODULE ! {get,Key,self()},
    receive
        {reply,Reply} -> Reply
    end.

del(Key) ->
    ?MODULE ! {del,Key,self()},
    receive
        {reply,Reply} -> Reply
    end.
    
stop() ->
    case is_started() of
        true  ->
            ?MODULE ! die;
        false ->
            {not_started}
    end.
    
loop(Socket) ->
    receive
        {start, Address, Port} ->
            case gen_tcp:connect(Address,Port,?TCP_OPTIONS) of
                {ok,NewSocket} -> 
                    loop(NewSocket);
                {error,Reason} ->
                    io:fwrite("Client: Failed connecting to socket; " ++ Reason)
            end;

        {del,Key,Pid} ->
            clientiface:make_and_send(Socket,"DEL",Key),
            Reply = clientiface:get_message(Socket),
            Pid ! {reply, Reply},
            loop(Socket);
        {get,Key,Pid} ->
            clientiface:make_and_send(Socket,"GET",Key),
            Reply = clientiface:get_message(Socket),
            Pid ! {reply, Reply},
            loop(Socket);
        {put,Key,Value,Pid} ->
            clientiface:make_and_send(Socket,"PUT",Key,Value),
            Reply = clientiface:get_message(Socket),
            Pid ! {reply, Reply},
            loop(Socket);
        die ->
            gen_tcp:close(Socket),
            ok;
        _   ->
            io:format("clientovich: Unknown message!"),
            loop(Socket)
    end.

is_started() ->
    case whereis(?MODULE) of
        undefined -> false;
        _         -> true
    end.
    
%print_response({_Code,_Key,_Value}) ->
    %io:fwrite("Code: " ++ Code ++ ", Key: " ++ Key ++ ", Value: " ++ Value ++ "\n").
%    ok.
